﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Cars
{
    public class GameEngine
    {
        private List<Coordinate> objects;
        private ConsoleRenderer renderer;
        private bool isGameOver;
        private Random random;
        private Car car;
        private Keyboard keyboard;


        public GameEngine()
        {
            this.keyboard = new Keyboard();
            this.random = new Random();
            this.objects = new List<Coordinate>();
            this.renderer = new ConsoleRenderer();

            this.car = new Car(10);

            this.objects.Add(this.car);
        }
        
        public void Run()
        {
            Timer timer = new Timer(this.ExecuteTurn, null, 0, 1000);

            this.keyboard.onKeyPress += (sender, args) =>
            {
                this.OnArrowPress(this.keyboard.PressedKey);
            };

            while (!this.isGameOver)
            {
                this.keyboard.ProcessInput();
            }
        }

        private void OnArrowPress(ConsoleKey arrow)
        {
            this.renderer.Clear();
            if(arrow == ConsoleKey.LeftArrow)
            {
                if(this.car.X > 0)
                {
                this.car.X--;
                }
            }

            if (arrow == ConsoleKey.RightArrow)
            {
                if(this.car.X < EntryPoint.FieldWidth-1)
                {
                this.car.X++;
                }
            }
            var newObjectsList = new List<Coordinate>(this.objects);
            this.renderer.PrintAll(newObjectsList);
        }


        public void ExecuteTurn(object state)
        {
            this.renderer.Clear();

            foreach (var item in this.objects)
            {
                item.Move();
            }

            this.AddRock();
            this.renderer.PrintAll(this.objects);
            this.ClearObsoleteRooks();
            this.isGameOver = this.CheckIfGameOver();
        }
        

        private bool CheckIfGameOver()
        {
            var car = this.objects.First(x => x is Car);
            var rocks = this.objects.Where(x => !(x is Car));

            foreach (var rock in rocks)
            {
                if (rock == car)
                {
                    return true;
                }
            }

            return false;
        }

        private void AddRock()
        {
            int numberX = random.Next(0, EntryPoint.FieldWidth);
            int numberY = 0;
            objects.Add(new Rock(numberX, numberY));
        }

        private void ClearObsoleteRooks()
        {
            this.objects.RemoveAll(x => x.Y == EntryPoint.ScreenHeight - 1);
        }
        
    }
}
